package com.logistics.util;


import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

public class DateUtils {

   public static Date getNow() {
      return new Date();
   }

   /**
    * @description 计算时长
    * @param beginTime 开始时间
    * @param endTime 结束时间
    * @return String    返回类型
    */
   public static String getTimeStr(Date beginTime,Date endTime) {
      /**
       * 秒
       */
      double timeSecend = Math.ceil(Double.parseDouble(String.valueOf((beginTime.getTime() - endTime.getTime())/1000)));
      String timeStr = "";
      if(timeSecend < 60){
         timeStr = ((int)Math.ceil(timeSecend)) + "秒前";

      }else if(timeSecend < 60*60 ){
         timeStr = ((int)Math.ceil(timeSecend/60)) + "分钟前";

      }else if(timeSecend < 60 * 60 * 24 ){
         timeStr = ((int)Math.ceil(timeSecend/60/60)) + "小时前";

      }else if(timeSecend  < 60 * 60 * 24 * 7 ){
         timeStr = ((int)Math.ceil(timeSecend/60/60/24)) + "天前";

      }else if(timeSecend < 60 * 60 * 24 * 7 * 4){
         timeStr = ((int)Math.ceil(timeSecend/60/60/24/7)) + "周前";

      }else if(timeSecend < 60 * 60 * 24 * 365){
         timeStr = ((int)Math.ceil(timeSecend/60/60/24/30)) + "月前";

      }else {
         timeStr = ((int)Math.ceil(timeSecend/60/60/24/365)) + "年前";
      }
      return timeStr;
   }

   /**
    * 将字符串转成格式的日期
    * @date 2015-11-23
    * @param strDate 需要转换的字符串
    * @param format  转换格式，如：yyyy-MM-dd HH:mm:ss
    * @return
    */
   public static Date formatStrToDate(String strDate, String format) {
      Date date = null;
      SimpleDateFormat sdf = new SimpleDateFormat(format);
      try {
         date = sdf.parse(strDate);
      } catch (ParseException e) {

      }
      return date;
   }

   /**
    * 将日期转成字符串
    * @date 2015-11-23
    * @param date  需要转换的日期
    * @param format   转换格式，如：yyyy-MM-dd HH:mm:ss
    * @return
    */
   public static String formatDateToStr(Date date, String format) {
      SimpleDateFormat sdf = new SimpleDateFormat(format);
      return sdf.format(date);
   }

   /**
    * @description 获当前日期的的前一个月
    * @return Date    返回类型
    * @date 2016年1月11日 下午4:11:51
    */
   public static Date getLastMonthDate() {
      Calendar lastMonthDate = Calendar.getInstance();
      lastMonthDate.add(Calendar.MONTH, -1);
      return lastMonthDate.getTime();
   }

   /**
    * @description 获取某一日期的前一天
    * @param date
    * @return Date    返回类型
    * @date 2016年1月11日 下午4:14:25
    */
   public static Date getBeforeDay(Date date) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(date);
      calendar.add(Calendar.DAY_OF_MONTH, -1);
      date = calendar.getTime();
      return date;
   }

   /**
    * @description 将某一日期增加若干月
    * @param curr
    * @param months 增加的月份数，若为负数，则表示往前几个月
    * @return Date    返回类型
    * @date 2016年1月11日 下午3:44:57
    */
   public static Date addMonths(Date curr, int months) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.MONTH, months);
      return calendar.getTime();
   }

   /**
    * @description 将某一日期增加若干天
    * @param curr
    * @param days
    * @return Date    返回类型
    * @date 2016年1月11日 下午3:43:03
    */
   public static Date addDays(Date curr, int days) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.DAY_OF_MONTH, days);
      return calendar.getTime();
   }

   /**
    * 将某一日期减少若干天
    * @param curr
    * @param days
    * @return
    */
   public static Date reduceDays(Date curr, int days) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.DAY_OF_MONTH, days);
      return calendar.getTime();
   }

   /**
    * @description 将某一日期增加若干小时
    * @param date
    * @param hours
    * @return Date    返回类型
    * @date 2016年1月11日 下午3:55:13
    */
   public static Date addHours(Date date, int hours) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(date);
      calendar.add(Calendar.HOUR, hours);
      return calendar.getTime();
   }


   /**
    * @description 将某一日期增加若干分钟
    * @param curr
    * @param minutes
    * @return Date    返回类型
    * @date 2016年1月11日 下午3:43:21
    */
   public static Date addMinutes(Date curr, int minutes) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.MINUTE, minutes);
      return calendar.getTime();
   }

   /**
    * 获取当前时间加上传入的秒数
    * @since 2015-11-05
    * @return
    */
   public static Date getAddSeconds(int seconds) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(new Date());
      calendar.add(Calendar.SECOND, +seconds);
      Date delayTime = calendar.getTime();
      return delayTime;
   }
   /**
    *
    * @description 将某一日期增加若干周
    * @param curr
    * @param weeks
    * @return
    * @return Date    返回类型
    * @throws
    * @date 2017年8月21日 下午7:36:12
    */
   public static Date addWeeks(Date curr, int weeks) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.WEDNESDAY, weeks);
      return calendar.getTime();
   }
   /**
    *
    * @description 将某一日期增加若干年
    * @param curr
    * @param years
    * @return
    * @return Date    返回类型
    * @throws
    * @date 2017年8月21日 下午7:36:12
    */
   public static Date addYears(Date curr, int years) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(curr);
      calendar.add(Calendar.YEAR, years);
      return calendar.getTime();
   }

   /**
    * 取两个Date之间的天数差<br>
    * <br>
    * 例：newerDate是6月3日，olderDate是5月31日，则应返回3 <br>
    * 一个更极端的列子：newerDate是6月3日 00:01，olderDate是6月2日
    * 23:59，则应返回1，说明相差一天，即便实际上只差2分钟 <br>
    * 此代码来自网上 <br>
    * http://blog.csdn.net/rmartin/article/details/1452867
    *
    * @param newerDate
    * @param olderDate
    * @return
    */
   public static int daysBetween(Date newerDate, Date olderDate) {
      Calendar cNow = Calendar.getInstance();
      Calendar cReturnDate = Calendar.getInstance();
      cNow.setTime(newerDate);
      cReturnDate.setTime(olderDate);
      setTimeToMidnight(cNow);
      setTimeToMidnight(cReturnDate);
      long todayMs = cNow.getTimeInMillis();
      // zyb 2015/4/8 将日期中毫秒归零，以避免错误
      todayMs = (todayMs / 1000L) * 1000L;
      long returnMs = cReturnDate.getTimeInMillis();
      // zyb 2015/4/8 将日期中毫秒归零，以避免错误
      returnMs = (returnMs / 1000L) * 1000L;
      long intervalMs = todayMs - returnMs;
      return millisecondsToDays(intervalMs);
   }

   /**
    * 算出两个日期之间相差的分钟数
    *
    * @param newerDate
    * @param olderDate
    * @return
    */
   public static int MinutesBetween(Date newerDate, Date olderDate) {
      Calendar cNow = Calendar.getInstance();
      Calendar cReturnDate = Calendar.getInstance();
      cNow.setTime(newerDate);
      cReturnDate.setTime(olderDate);
      long todayMs = cNow.getTimeInMillis();
      long returnMs = cReturnDate.getTimeInMillis();
      long intervalMs = todayMs - returnMs;
      intervalMs = intervalMs / (1000 * 60);
      return (int) intervalMs;
   }

   private static int millisecondsToDays(long intervalMs) {
      return (int) (intervalMs / (1000 * 86400));
   }

   /**
    * @description 设置时间为0点
    */
   public static Date setTimeToMidnight(Date date) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(date);
      calendar.set(Calendar.HOUR_OF_DAY, 0);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return calendar.getTime();
   }
   /**
    * @description 设置时间为0点
    */
   public static Date setTimeToMidnight(Calendar calendar) {
      calendar.set(Calendar.HOUR_OF_DAY, 0);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return calendar.getTime();
   }

   /**
    * @description 设置某一日期的时间
    * @param date
    * @param hour
    * @return Date    返回类型
    * @date 2016年2月22日 下午3:58:48
    */
   public static Date setHours(Date date, int hour) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(date);
      calendar.set(Calendar.HOUR_OF_DAY, hour);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      return calendar.getTime();
   }


   /**
    * @description 返回当前时间的所在月的第一天的0:0:0
    */
   public static Date getFirstMomentOfThisMonth(Date date) {
      Calendar calendar = Calendar.getInstance();
      calendar.setTime(date);
      calendar.set(calendar.DAY_OF_MONTH, 1);
      calendar.set(Calendar.HOUR_OF_DAY, 0);
      calendar.set(Calendar.MINUTE, 0);
      calendar.set(Calendar.SECOND, 0);
      calendar.set(Calendar.MILLISECOND, 0);
      return calendar.getTime();
   }

   /**
    * 返回 计算每个月的天数
    * @param year  XXXX年
    * @param month  XX月
    * @return
    */
   public static int getDaysOfMonth2(int year, int month) {
      int days = 0;
      if (month == 1 || month == 3 || month == 5 || month == 7 || month == 9
            || month == 10 || month == 12) {
         days = 31;
      } else if (month == 4 || month == 6 || month == 8 || month == 11) {
         days = 30;
      } else { // 2月份，闰年29天、平年28天
         if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            days = 29;
         } else {
            days = 28;
         }
      }
      return days;
   }
   /**
    * 获取时间差，秒数
    */
   public static long getSecond(Date beginTime,Date endTime)throws Exception{
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      String statrsTime= sdf.format(beginTime).toString();
      String orveTime  =  sdf.format(endTime).toString();
      // 将截取到的时间字符串转化为时间格式的字符串 **/
      Date begin=sdf.parse(statrsTime);
      Date end = sdf.parse(orveTime);
      long Second=(end.getTime()-begin.getTime())/1000;//除以1000是为了转换成秒
      return Second;
   }

   /**
    * 比较时间大小
    */
   public static Boolean compareToDate(Date registerDate,Date nextDayDate){
      Calendar c1=Calendar.getInstance();
      Calendar c2=Calendar.getInstance();
      boolean isflag=false;
      try {
         c1.setTime(registerDate);
         c2.setTime(nextDayDate);
      } catch (Exception e) {
         e.printStackTrace();
      }
      int result=c1.compareTo(c2);
      if(result<0){
         isflag=false;
      }else{
         isflag=true;
      }
      return isflag;
   }

   /**
    * 将传入的参数封装成枚举进行return
    * @author 刘松
    * @param errorCode
    * @param errorMessage
    * @param innMessage
    * @return
    */


   /**
    * 获取当年的最后一天  返回的日期格式 yyyy-MM-dd
    * @return
    */
   public static String getYearLast(){
      Calendar currCal=Calendar.getInstance();
      int year =currCal.get(Calendar.YEAR);
      currCal.clear();
      currCal.set(Calendar.YEAR,year);
      currCal.roll(Calendar.DAY_OF_YEAR, -1);
      SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");
      return sm.format(currCal.getTime());
   }



   //==================转换 iso时间为 date
   public static Date formatDate2(String time){
      SimpleDateFormat sdf =   new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      try {
         return sdf.parse(time);
      } catch (ParseException e) {
         e.printStackTrace();
         return null;
      }
   }
   public static Date fromISODate(String time){
      if(!time.matches("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}.\\d{3}Z")){
         return null;
      }
      time=time.replaceFirst("T", " ").replaceFirst(".\\d{3}Z", "");
      Date date=formatDate2(time);
      Calendar ca=Calendar.getInstance();
      ca.setTime(date);
      ca.add(Calendar.HOUR_OF_DAY, 8);
      return ca.getTime();
   }
   /**
    * 传入Data类型日期，返回字符串类型时间（ISO8601标准时间）
    * @param date
    * @return
    */
   public static String getISO8601Timestamp(Date date){
      TimeZone tz = TimeZone.getTimeZone("UTC");
      DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
      df.setTimeZone(tz);
      String nowAsISO = df.format(date);
      return nowAsISO;
   }

   /**
    * 时间戳转日期
    * @param ms
    * @return
    */
   public static Date transForDate(Long ms){
      if(ms==null){
         ms=(long)0;
      }
      long msl=(long)ms;
      SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      Date temp=null;
      if(ms!=null){
         try {
            String str=sdf.format(msl);
            temp=sdf.parse(str);
         } catch (ParseException e) {
            e.printStackTrace();
         }
      }
      return temp;
   }


   /**
    * 获取给定月的最后一天
    *
    * @param date
    * @return
    */
   public static Date getLastdayOfMonth(Date date) {
      Calendar ca = Calendar.getInstance();
      ca.setTime(date);// someDate 为你要获取的那个月的时间
      ca.set(Calendar.DAY_OF_MONTH, 1);
      ca.add(Calendar.MONTH, 1);
      ca.add(Calendar.DAY_OF_MONTH, -1);
   // 最后一天
      Date lastDate = ca.getTime();
      return lastDate;
   }


   /**
    * 获取给定月的第一天
    *
    * @param date
    * @return
    */
   public static Date getFirstdayOfMonth(Date date) {
      Calendar ca = Calendar.getInstance();
      ca.setTime(date);// someDate 为你要获取的那个月的时间
      ca.set(Calendar.DAY_OF_MONTH, 1);
      // 第一天
      Date firstDate = ca.getTime();
      return firstDate;
   }



   /**
    *
    * @Description: 传入时间，获取当年的第一天
    *
    * @Param: date
    * @return: java.util.Date
    * @date: 2018-07-17 13:48
    */
   public static Date getFirstDayDateOfYear(Date date) {
      Calendar ca = Calendar.getInstance();
      ca.setTime(date);// someDate 为你要获取的那年的时间
      ca.set(Calendar.DAY_OF_YEAR, 1);
      // 第一天
      Date firstDate = ca.getTime();
      return firstDate;
   }

   /**
    *
    * @Description: 传入时间，获取当年的最后第一天
    *
    * @Param: date
    * @return: java.util.Date
    * @date: 2018-07-17 13:48
    */
   public static Date getLastDayOfYear(Date date) {
      Calendar ca = Calendar.getInstance();
      ca.setTime(date);// someDate 为你要获取的那年的时间
      ca.set(Calendar.DAY_OF_YEAR, 1);
      ca.add(Calendar.YEAR, 1);
      ca.add(Calendar.DAY_OF_YEAR, -1);
      // 最后一天
      Date lastDate = ca.getTime();
      return lastDate;
   }

  /**
   *
   * @Description: 获取年

   */
   public static String getCurrentYear(){
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
      Date date = new Date();
      return sdf.format(date);
   }

   /**
    * 获取本年度12个月的月份
    * @throws ParseException
    */
   public static List<String> getMonth(){
      // 获取当前日期
      Calendar calendar = Calendar.getInstance();

      // 获取当前年份
      int year = calendar.get(Calendar.YEAR);

      // 存储月份的列表
      List<String> months = new ArrayList<>();

      // 遍历12个月份
      for (int month = Calendar.JANUARY; month <= Calendar.DECEMBER; month++) {
         // 设置为当前年份的月份
         calendar.set(year, month, 1);

         // 获取月份的字符串表示
         String monthString = calendar.getDisplayName(Calendar.MONTH, Calendar.LONG, java.util.Locale.getDefault());

         // 添加到列表中
         months.add(monthString);
      }

      // 输出12个月份
      for (String month : months) {
         System.out.println(month);
      }
      return months;
   }

   /**
    * 获取本年度每个月的开始和结束日期
    * @return
    */
   public static Map<String,String> getStartDayAndEndDayByMonthInYear(){

      Map<String,String> dayMap = new LinkedHashMap<String,String>();

      SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

      Calendar calendar = Calendar.getInstance();
      int currentYear = calendar.get(Calendar.YEAR);

      for (int month = 0; month < 12; month++) {

         String startDay = "";
         String endDay = "";
         // 设置年份和月份
         calendar.set(Calendar.YEAR, currentYear);
         calendar.set(Calendar.MONTH, month);

         // 获取每个月的第一天
         calendar.set(Calendar.DAY_OF_MONTH, 1);
         System.out.print("第一天: " + format.format(calendar.getTime())+"\t");
         startDay=format.format(calendar.getTime());
         // 获取每个月的最后一天
         calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
         System.out.println("最后一天: " + format.format(calendar.getTime()));
         endDay=format.format(calendar.getTime());
         dayMap.put(startDay+" 00:00:00",endDay+" 00:00:00");

      }
      return dayMap;
   }

  public static void main(String[] args) throws ParseException {
     getMonth();

  }

//   public static void main(String[] args) {
//      Map<Integer, Pair<LocalDate, LocalDate>> monthDates = getMonthFirstAndLastDays();
//
//      for (Map.Entry<Integer, Pair<LocalDate, LocalDate>> entry : monthDates.entrySet()) {
//         int month = entry.getKey();
//         Pair<LocalDate, LocalDate> dates = entry.getValue();
//         LocalDate firstDay = dates.getLeft();
//         LocalDate lastDay = dates.getRight();
//
//         System.out.println("Month: " + month);
//         System.out.println("First day: " + firstDay);
//         System.out.println("Last day: " + lastDay);
//         System.out.println();
//      }
//   }
//
//   public static Map<Integer, Pair<LocalDate, LocalDate>> getMonthFirstAndLastDays() {
//      Map<Integer, Pair<LocalDate, LocalDate>> monthDates = new HashMap<>();
//      LocalDate currentDate = LocalDate.now();
//      int currentYear = currentDate.getYear();
//
//      for (int i = 1; i <= 12; i++) {
//         LocalDate firstDay = LocalDate.of(currentYear, i, 1);
//         LocalDate lastDay = firstDay.with(TemporalAdjusters.lastDayOfMonth());
//
//         monthDates.put(i, ImmutablePair.of(firstDay, lastDay));
//      }
//
//      return monthDates;
//   }


//   public static void main(String[] args) {
//      int year = LocalDate.now().getYear(); // 获取当前年份
//
//      for (int month = 1; month <= 12; month++) {
//         YearMonth yearMonth = YearMonth.of(year, month); // 构造YearMonth对象
//         LocalDate firstDayOfMonth = yearMonth.atDay(1); // 获取月份的第一天
//         LocalDate lastDayOfMonth = yearMonth.atEndOfMonth(); // 获取月份的最后一天
//
//         System.out.println("Month: " + month);
//         System.out.println("First day: " + firstDayOfMonth);
//         System.out.println("Last day: " + lastDayOfMonth);
//         System.out.println("--------------------");
//      }
//   }

}
